package ln.gather.jsr.common.util;

import java.util.*;

/**
 * 类的序列化工具
 */
public class Serializers {

    private final Map<Class<?>, List<Serializer>> typeSerializers = new HashMap<>();

    private final ClassLoader classLoader;

    public Serializers() {
        this(Thread.currentThread().getContextClassLoader());
    }

    public Serializers(ClassLoader classLoader) {
        this.classLoader = classLoader;
    }

    /**
     * 加载SPI实现并按照顺序放在序列化列表中
     */
    public void loadSPI() {
        ServiceLoader.load(Serializer.class).forEach(serializer -> {
            List<Class<?>> typeArguments = TypeUtils.resolveTypeArguments(serializer.getClass());
            Class<?> targetClass = typeArguments.isEmpty() ? Object.class : typeArguments.get(0);
            List<Serializer> serializers = typeSerializers.computeIfAbsent(targetClass, k -> new LinkedList<>());
            serializers.add(serializer);
            serializers.sort(PriorityComparator.INSTANCE);
        });
    }

    public Serializer getMostCompatible(Class<?> serializedType) {
        Serializer<Object> serializer = getHighestPriority(serializedType);
        if(serializer == null) {
            serializer = getLowestPriority(serializedType);
        }
        return serializer;
    }

    private <T> Serializer<T> getLowestPriority(Class<?> serializedType) {
        List<Serializer<T>> serializers;
        return (serializers = get(serializedType)).isEmpty()? null: serializers.get(serializers.size() - 1);
    }

    private <T> Serializer<T> getHighestPriority(Class<?> serializedType) {
        List<Serializer<T>> serializers;
        return (serializers = get(serializedType)).isEmpty()? null: serializers.get(0);
    }

    private <T> List<Serializer<T>> get(Class<?> serializedType) {
        return (List) typeSerializers.getOrDefault(serializedType, Collections.emptyList());
    }

}
